home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / Framewrk / FWPart / FWLnkSrc.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  11.5 KB  |  393 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWLnkSrc.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWFrameW.hpp"
  11.  
  12. #ifndef FWLNKSRC_H
  13. #include "FWLnkSrc.h"
  14. #endif
  15.  
  16. // ----- Framework Includes -----
  17.  
  18. #ifndef FWPART_H
  19. #include "FWPart.h"
  20. #endif
  21.  
  22. #ifndef FWPRESEN_H
  23. #include "FWPresen.h"
  24. #endif
  25.  
  26. #ifndef FWLNKITE_H
  27. #include "FWLnkIte.h"
  28. #endif
  29.  
  30. #ifndef FWCLNINF_H
  31. #include "FWClnInf.h"
  32. #endif
  33.  
  34. #ifndef FWINTER_H
  35. #include "FWInter.h"
  36. #endif
  37.  
  38. #ifndef FWPRMISE_H
  39. #include "FWPrmise.h"
  40. #endif
  41.  
  42. #ifndef FWLNKCMD_H
  43. #include "FWLnkCmd.h"
  44. #endif
  45.  
  46. #ifndef FWSESION_H
  47. #include "FWSesion.h"
  48. #endif
  49.  
  50. // ----- Foundation Includes -----
  51.  
  52. #ifndef FWPRIDEB_H
  53. #include "FWPriDeb.h"
  54. #endif
  55.  
  56. #ifndef FWBARRAY_H
  57. #include "FWBArray.h"
  58. #endif
  59.  
  60. // ----- OpenDoc Includes -----
  61.  
  62. #ifndef SOM_Module_OpenDoc_StdProps_defined
  63. #include <StdProps.xh>
  64. #endif
  65.  
  66. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  67. #include <StdTypes.xh>
  68. #endif
  69.  
  70. #ifndef SOM_ODStorageUnit_xh
  71. #include <StorageU.xh>
  72. #endif
  73.  
  74. #ifndef SOM_ODLinkSpec_xh
  75. #include <LinkSpec.xh>
  76. #endif
  77.  
  78. #ifndef SOM_ODLinkSource_xh
  79. #include <LinkSrc.xh>
  80. #endif
  81.  
  82. //========================================================================================
  83. //    Runtime information
  84. //========================================================================================
  85.  
  86. #ifdef FW_BUILD_MAC
  87. #pragma segment odflinking
  88. #endif
  89.  
  90. //========================================================================================
  91. //    Template Instantiations
  92. //========================================================================================
  93.  
  94. FW_DEFINE_AUTO_TEMPLATE(FW_TOrderedCollectionIterator, FW_CLinkSource)
  95. FW_DEFINE_AUTO_TEMPLATE(FW_TOrderedCollection, FW_CLinkSource)
  96.  
  97. #ifdef FW_USE_TEMPLATE_PRAGMAS
  98.  
  99. #pragma template_access public
  100. #pragma template FW_TOrderedCollection<FW_CLinkSource>
  101. #pragma template FW_TOrderedCollectionIterator<FW_CLinkSource>
  102.  
  103. #endif
  104.  
  105. //========================================================================================
  106. //    class FW_CLinkSource
  107. //========================================================================================
  108.  
  109. //---------------------------------------------------------------------------------------
  110. //    FW_CLinkSource::FW_CLinkSource
  111. //---------------------------------------------------------------------------------------
  112.  
  113. FW_CLinkSource::FW_CLinkSource(Environment* ev, 
  114.                                ODUpdateID updateID,
  115.                                FW_CPresentation* presentation)
  116. :    FW_CLink(ev, presentation),
  117.     fODLinkSource(NULL),
  118.     fUpdateID(updateID),
  119.     fPendingID(updateID),
  120.     fDataInterchange(presentation->GetPart(ev)->GetDataInterchange(ev)),
  121.     fLinkPromise(NULL),
  122.     fPendingCommand(NULL)
  123. {
  124. }
  125.  
  126. //---------------------------------------------------------------------------------------
  127. //    FW_CLinkSource::~FW_CLinkSource
  128. //---------------------------------------------------------------------------------------
  129.  
  130. FW_CLinkSource::~FW_CLinkSource()
  131. {
  132.     if (fODLinkSource)
  133.     {
  134.         FW_SOMEnvironment ev;
  135.         fODLinkSource->Release(ev);
  136.     }
  137.     
  138.     if (fLinkPromise)
  139.         delete fLinkPromise;
  140. }
  141.  
  142. //---------------------------------------------------------------------------------------
  143. //    FW_CLinkSource::SetODLinkSource
  144. //---------------------------------------------------------------------------------------
  145.  
  146. void FW_CLinkSource::SetODLinkSource(Environment* ev, ODLinkSource* odLinkSource)
  147. {
  148.     FW_ASSERT(odLinkSource!=NULL);
  149.     FW_ASSERT(fODLinkSource==NULL);
  150.     
  151.     fODLinkSource = odLinkSource;
  152.     odLinkSource->Acquire(ev);
  153. }
  154.  
  155. //---------------------------------------------------------------------------------------
  156. //    FW_CLinkSource::PrivSetPromise
  157. //---------------------------------------------------------------------------------------
  158.  
  159.  
  160.  
  161. //---------------------------------------------------------------------------------------
  162. //    FW_CLinkSource::ContentUpdated
  163. //---------------------------------------------------------------------------------------
  164.  
  165. void FW_CLinkSource::ContentUpdated(Environment* ev, ODUpdateID updateID,
  166.                                     FW_Boolean forceUpdate)
  167. {
  168.     FW_Boolean justRewrite = (updateID == kODUnknownUpdate) && forceUpdate;
  169.     ODUpdateID newID = updateID ? updateID : justRewrite ? fUpdateID :  FW_CSession::UniqueUpdateID(ev);
  170.  
  171.     // Don't update unless we really have to
  172.     if (this->IsOKtoUpdate(ev, forceUpdate))
  173.     {
  174.         ODLinkKey key;
  175.         FW_VOLATILE(key);
  176.  
  177.         if (fODLinkSource->Lock(ev, 0, &key)) 
  178.         {
  179.  
  180.             FW_TRY
  181.             {
  182.                 fODLinkSource->Clear(ev, newID, key);
  183.                 // Clear must be followed by GetContentStorageUnit, which writes out a new set of promises
  184.                 ODStorageUnit* linkSU = fODLinkSource->GetContentStorageUnit(ev, key);
  185.  
  186.                 ExternalizeLinkContent(ev, linkSU);
  187.  
  188.                 if (!justRewrite)
  189.                     fODLinkSource->ContentUpdated(ev, newID, key);
  190.             }
  191.             FW_CATCH_BEGIN
  192.             FW_CATCH_EVERYTHING()
  193.             {
  194.                 fODLinkSource->Clear(ev, fUpdateID, key);
  195.                 fODLinkSource->Unlock(ev, key);    
  196.                 FW_THROW_SAME();
  197.             }
  198.             FW_CATCH_END
  199.     
  200.             fODLinkSource->Unlock(ev, key);                    
  201.         }
  202.     }
  203.     
  204.     fUpdateID = newID;
  205. }
  206.  
  207. //---------------------------------------------------------------------------------------
  208. //    FW_CLinkSource::ResolveAllPromises
  209. //----------------------------------------------------------------------------------------
  210. // [HLX] Might not be completely right ????
  211.  
  212.  
  213.  
  214. //---------------------------------------------------------------------------------------
  215. //    FW_CLinkSource::HasEmbeddedFrame
  216. //----------------------------------------------------------------------------------------
  217. FW_Boolean FW_CLinkSource::HasEmbeddedFrame(Environment* ev, ODFrame* odEmbeddedFrame)
  218. {
  219. FW_UNUSED(ev);
  220. FW_UNUSED(odEmbeddedFrame); 
  221.  
  222.     // Should be overridden if the part supports embedding.
  223.     // Return TRUE if odEmbeddedFrame is involved in this link source.
  224.  
  225.     return FALSE;
  226. }
  227.  
  228. //---------------------------------------------------------------------------------------
  229. //    FW_CLinkSource::IsOKtoUpdate
  230. //----------------------------------------------------------------------------------------
  231. FW_Boolean FW_CLinkSource::IsOKtoUpdate(Environment* ev, FW_Boolean forceUpdate)
  232. {
  233.     return (forceUpdate || fODLinkSource->IsAutoUpdate(ev));
  234. }
  235.  
  236. //---------------------------------------------------------------------------------------
  237. //    FW_CLinkSource::BreakLink
  238. //----------------------------------------------------------------------------------------
  239. void FW_CLinkSource::BreakLink(Environment* ev)
  240. {
  241.     fODLinkSource->SetSourcePart(ev, (ODStorageUnit*) kODNULL);
  242.     fUpdateID = kODUnknownUpdate;
  243. }
  244.  
  245. //---------------------------------------------------------------------------------------
  246. //    FW_CLinkSource::RestoreLink
  247. //----------------------------------------------------------------------------------------
  248. void FW_CLinkSource::RestoreLink(Environment* ev, FW_CPart* part)
  249. {
  250.     fODLinkSource->SetSourcePart(ev, part->GetStorageUnit(ev));
  251. }
  252.  
  253. //---------------------------------------------------------------------------------------
  254. //    FW_CLinkSource::ExternalizeLink
  255. //----------------------------------------------------------------------------------------
  256. void FW_CLinkSource::ExternalizeLink(Environment* ev, ODStorageUnit* storageUnit,
  257.                                       FW_CCloneInfo* cloneInfo)
  258. {
  259.     //-- Storage unit must be focused to property kODPropContents, value linkSourceFormat
  260.     ODStorageUnitRef suRef;
  261.     fODLinkSource->Externalize(ev);
  262.  
  263.     ODID linkID = fODLinkSource->GetID(ev);
  264.     if (cloneInfo != NULL)
  265.     {
  266.         linkID = cloneInfo->Clone(ev, linkID, 0, 0);
  267.         // May not have been able to clone the link
  268.         if (!cloneInfo->GetFromDraft(ev)->IsValidID(ev, linkID))
  269.             return;
  270.     }
  271.  
  272.     //--- Write the link version number ---
  273.     long version = FW_kLinkVersionNumber;
  274.     FW_CByteArray byteArray(&version, sizeof(long));
  275.     storageUnit->SetValue(ev, byteArray);
  276.  
  277.     //--- Write a reference to the link ---
  278.     storageUnit->GetStrongStorageUnitRef(ev, linkID, suRef);
  279.     byteArray.Set(&suRef, sizeof(ODStorageUnitRef));
  280.     storageUnit->SetValue(ev, byteArray);
  281.  
  282.     //--- Write the update ID ---
  283.     byteArray.Set(&fUpdateID, sizeof(ODUpdateID));
  284.     storageUnit->SetValue(ev, byteArray);
  285.  
  286.     //-- Write out data specific to this part's link --
  287.     this->DoExternalizeLink(ev, storageUnit, cloneInfo);
  288. }
  289.  
  290. //---------------------------------------------------------------------------------------
  291. //    FW_CLinkSource::PrivLinkEstablished
  292. //---------------------------------------------------------------------------------------
  293. void FW_CLinkSource::PrivLinkEstablished(Environment* ev)
  294. {
  295.     FW_ASSERT(fODLinkSource != NULL);
  296.     FW_CPart* part = fPresentation->GetPart(ev);
  297.     fODLinkSource->SetSourcePart(ev, part->GetODPart(ev)->GetStorageUnit(ev));
  298.  
  299.     //---- Change the link status of affected embedded frames (part-specific)
  300.     this->LinkEstablished(ev);
  301.  
  302.     //--- Force the first update using a new change ID
  303.     ODUpdateID change = FW_CSession::UniqueUpdateID(ev);
  304.     this->ContentUpdated(ev, change, TRUE);    
  305. }
  306.  
  307. //---------------------------------------------------------------------------------------
  308. //    FW_CLinkSource::GetFrameToRevealLink
  309. //---------------------------------------------------------------------------------------
  310. FW_CFrame* FW_CLinkSource::GetFrameToRevealLink(Environment* ev)
  311. {
  312.     // Return a display frame suitable for showing this link.
  313.     // Override to return a frame different from the default (the first one).
  314.     FW_CPresentationFrameIterator piter(ev, fPresentation);
  315.     return piter.First(ev);
  316. }
  317.  
  318. //---------------------------------------------------------------------------------------
  319. //    FW_CLinkSource::RevealLinkSource
  320. //---------------------------------------------------------------------------------------
  321. void FW_CLinkSource::RevealLinkSource(Environment* ev, FW_CFrame* frame)
  322. {
  323. FW_UNUSED(ev);
  324. FW_UNUSED(frame);
  325.     // Override to select the content in this link source
  326. }
  327.  
  328. //---------------------------------------------------------------------------------------
  329. //    FW_CLinkSource::ShowLinkInfo
  330. //---------------------------------------------------------------------------------------
  331. void FW_CLinkSource::ShowLinkInfo(Environment* ev, FW_CFrame* frame, FW_CLinkManager* linkMgr)
  332. {
  333.     ODLinkInfoResult infoResult;
  334.  
  335.     if (fODLinkSource->ShowLinkSourceInfo(ev, frame->GetActiveFacet(ev), fUpdateID, true, &infoResult))
  336.     {
  337.         switch (infoResult.action)
  338.         {
  339.             case kODLinkInfoBreakLink:
  340.                 {
  341.                 // Create and execute an undoable command to break the link
  342.                 FW_CBreakLinkSourceCommand* cmd = FW_NEW(FW_CBreakLinkSourceCommand, (ev, frame, this, linkMgr)); 
  343.                 cmd->Execute(ev);
  344.                 }
  345.                 break;
  346.  
  347.             case kODLinkInfoUpdateNow:
  348.                 this->ContentUpdated(ev, FW_CSession::UniqueUpdateID(ev), true);
  349.                 break;
  350.  
  351.             case kODLinkInfoOk:
  352.                 if (infoResult.autoUpdate != fODLinkSource->IsAutoUpdate(ev))
  353.                 {
  354.                     fODLinkSource->SetAutoUpdate(ev, infoResult.autoUpdate);
  355.                     if (infoResult.autoUpdate)
  356.                         if (fUpdateID != fODLinkSource->GetUpdateID(ev))
  357.                         {
  358.                             // changed from manual to automatic updates, and
  359.                             // the link is out of date-- update it now
  360.                             this->ContentUpdated(ev, FW_CSession::UniqueUpdateID(ev), true);
  361.                         }
  362.                 }
  363.                 break;
  364.         }
  365.     }
  366. }
  367.  
  368. //---------------------------------------------------------------------------------------
  369. //    FW_CLinkSource::SetLinkPromise
  370. //---------------------------------------------------------------------------------------
  371. void FW_CLinkSource::SetLinkPromise(Environment* ev, FW_CPromise* promise)
  372. {
  373. FW_UNUSED(ev);
  374.  
  375.     // Implementations can override this, if for example, they want to just keep reusing
  376.     // the same promise instead of creating a new one each time the link updates.    
  377.     
  378.     FW_ASSERT(!promise || promise->PrivGetLinkSource(ev) == this);
  379.     
  380.     if (fLinkPromise != promise)
  381.     {
  382.         if (fLinkPromise)
  383.             delete fLinkPromise;
  384.         
  385.         fLinkPromise = promise;
  386.     }
  387. }
  388.  
  389.  
  390.  
  391.  
  392.  
  393.